package com.manage.modules.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.manage.common.constant.UserConstants;
import com.manage.common.exception.CustomException;
import com.manage.modules.domain.TBaseStationType;
import com.manage.modules.domain.TreeSelectModel;
import com.manage.modules.mapper.TBaseStationTypeMapper;
import com.manage.modules.service.ITBaseStationTypeService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 站点分类Service业务层处理
 *
 * @author xu
 * 2021/8/11 17:35
 */
@Service
public class TBaseStationTypeServiceImpl extends ServiceImpl<TBaseStationTypeMapper, TBaseStationType> implements ITBaseStationTypeService {

    /**
     * 得到子节点列表
     */
    private List<TBaseStationType> getChildList(List<TBaseStationType> list, TBaseStationType t) {
        List<TBaseStationType> tlist = new ArrayList<>();
        for (TBaseStationType n : list) {
            if (Validator.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getStationTypeId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<TBaseStationType> list, TBaseStationType t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<TBaseStationType> list, TBaseStationType t) {
        // 得到子节点列表
        List<TBaseStationType> childList = getChildList(list, t);
        t.setChildren(childList);
        for (TBaseStationType tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    @Override
    public List<TBaseStationType> buildStationTypeTree(List<TBaseStationType> stationTypes) {
        List<TBaseStationType> returnList = new ArrayList<>();
        List<Long> tempList = new ArrayList<>();
        for (TBaseStationType stationType : stationTypes) {
            tempList.add(stationType.getStationTypeId());
        }
        for (TBaseStationType stationType : stationTypes) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(stationType.getParentId())) {
                recursionFn(stationTypes, stationType);
                returnList.add(stationType);
            }
        }
        if (returnList.isEmpty()) {
            returnList = stationTypes;
        }
        return returnList;
    }

    @Override
    public List<TreeSelectModel> buildStationTypeTreeSelect(List<TBaseStationType> stationTypes) {
        List<TBaseStationType> stationTypeTrees = buildStationTypeTree(stationTypes);
        return stationTypeTrees.stream().map(TreeSelectModel::new).collect(Collectors.toList());
    }


    @Override
    public TBaseStationType selectStationTypeById(Long typeId) {
        return getById(typeId);
    }

    @Override
    public boolean hasChildByTypeId(Long typeId) {
        int result = count(new LambdaQueryWrapper<TBaseStationType>()
                .eq(TBaseStationType::getParentId, typeId)
                .last("limit 1"));
        return result > 0;
    }

    @Override
    public int deleteStationTypeById(Long typeId) {
        return baseMapper.deleteById(typeId);
    }

    @Override
    public int selectNormalChildrenStationTypeById(Long typeId) {
        return count(new LambdaQueryWrapper<TBaseStationType>()
                .eq(TBaseStationType::getStationTypeState, 0)
                .apply("find_in_set({0}, ancestors)", typeId));
    }

    @Override
    public int updateStationType(TBaseStationType baseStationType) {
        TBaseStationType newParentStationType = getById(baseStationType.getParentId());
        TBaseStationType oldStationType = getById(baseStationType.getStationTypeId());
        if (Validator.isNotNull(newParentStationType) && Validator.isNotNull(oldStationType)) {
            String newAncestors = newParentStationType.getAncestors() + "," + newParentStationType.getStationTypeId();
            String oldAncestors = oldStationType.getAncestors();
            baseStationType.setAncestors(newAncestors);
            updateStationTypeChildren(baseStationType.getStationTypeId(), newAncestors, oldAncestors);
        }
        int result = baseMapper.updateById(baseStationType);
        if (UserConstants.DEPT_NORMAL.equals(baseStationType.getStationTypeState() + "")) {
            // 如果该站点分类是启用状态，则启用该站点分类的所有上级站点分类
            updateParentStationTypeStatus(baseStationType);
        }
        return result;
    }

    /**
     * 修改该站点分类的父级站点分类状态
     *
     * @param baseStationType 当前站点分类
     */
    private void updateParentStationTypeStatus(TBaseStationType baseStationType) {
        baseStationType = getById(baseStationType.getStationTypeId());
        update(null, new LambdaUpdateWrapper<TBaseStationType>()
                .set(baseStationType.getStationTypeState() != null,
                        TBaseStationType::getStationTypeState, baseStationType.getStationTypeState())
                .in(TBaseStationType::getStationTypeId, Arrays.asList(baseStationType.getAncestors().split(","))));
    }

    /**
     * 修改子元素关系
     *
     * @param typeId       被修改的站点分类ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateStationTypeChildren(Long typeId, String newAncestors, String oldAncestors) {
        List<TBaseStationType> children = list(new LambdaQueryWrapper<TBaseStationType>()
                .apply("find_in_set({0},ancestors)", typeId));
        for (TBaseStationType child : children) {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            updateBatchById(children);
        }
    }

    @Override
    public int insertStationType(TBaseStationType baseStationType) {
        TBaseStationType info = getById(baseStationType.getParentId());
        // 如果父节点不为正常状态,不允许新增子节点
        if (1 == info.getStationTypeState()) {
            throw new CustomException("站点分类停用，不允许新增");
        }
        baseStationType.setAncestors(info.getAncestors() + "," + baseStationType.getParentId());
        return baseMapper.insert(baseStationType);
    }

    @Override
    public List<TBaseStationType> selectStationTypeList(TBaseStationType baseStationType) {
        LambdaQueryWrapper<TBaseStationType> lqw = Wrappers.lambdaQuery();
        lqw
                .eq(baseStationType.getParentId() != null && baseStationType.getParentId() != 0, TBaseStationType::getParentId, baseStationType.getParentId())
                .eq(baseStationType.getStationTypeState() != null, TBaseStationType::getStationTypeState, baseStationType.getStationTypeState())
                .like(StrUtil.isNotBlank(baseStationType.getStationTypeName()), TBaseStationType::getStationTypeName, baseStationType.getStationTypeName())
                .orderByAsc(TBaseStationType::getOrderNum)
                .orderByAsc(TBaseStationType::getParentId);
        return list(lqw);
    }

    @Override
    public String checkStationTypeNameUnique(TBaseStationType baseStationType) {
        long typeId = Validator.isNull(baseStationType.getStationTypeId()) ? -1L : baseStationType.getStationTypeId();
        TBaseStationType info = getOne(new LambdaQueryWrapper<TBaseStationType>()
                .eq(TBaseStationType::getStationTypeName, baseStationType.getStationTypeName())
                .eq(TBaseStationType::getParentId, baseStationType.getParentId())
                .last("limit 1"));
        if (Validator.isNotNull(info) && info.getStationTypeId() != typeId) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
}
